home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / gui / gtlayout.lha / Source / LTP_TabClass.c < prev    next >
C/C++ Source or Header  |  1998-09-09  |  16KB  |  766 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1998 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. /*****************************************************************************/
  15.  
  16. #include <intuition/classes.h>
  17.  
  18. #include <exec/memory.h>
  19. #include <hardware/blit.h>
  20.  
  21. #include <clib/alib_protos.h>    /* For Coerce/Do/DoSuperMethod */
  22.  
  23. #include <stdarg.h>
  24.  
  25. /*****************************************************************************/
  26.  
  27. #include "Assert.h"
  28.  
  29. #ifdef DO_TAB_KIND    /* Support code */
  30.  
  31. #define TIA_Labels        (TAG_USER+0x90000)
  32. #define TIA_Font        (TAG_USER+0x90001)
  33. #define TIA_Screen        (TAG_USER+0x90002)
  34. #define TIA_Index        (TAG_USER+0x90003)
  35. #define TIA_DrawInfo    (TAG_USER+0x90004)
  36. #define TIA_SizeType    (TAG_USER+0x90005)
  37.  
  38. STATIC VOID
  39. DrawCap(struct RastPort *RPort,LONG Left,LONG Top,LONG Width,LONG Height,BOOL Flip)
  40. {
  41.     LONG x,y,da,MidX,MidY,r,Full,Push,Mult;
  42.  
  43.     Full = Height;
  44.  
  45.     Height = Width;
  46.  
  47.     MidX = Left;
  48.     MidY = Top + Height - 1;
  49.  
  50.     r = Height - 1;
  51.  
  52.     x = 0;
  53.     y = r;
  54.     da = r - 1;
  55.  
  56.     if(Flip)
  57.     {
  58.         Push = Width - 1;
  59.         Mult = -1;
  60.     }
  61.     else
  62.     {
  63.         Push = 0;
  64.         Mult = 1;
  65.     }
  66.  
  67.     do
  68.     {
  69.         if(da < 0)
  70.         {
  71.             y--;
  72.  
  73.             da += y * 2;
  74.         }
  75.  
  76.         WritePixel(RPort,Left + Push + Mult * (x + MidX - Left),-y + MidY);
  77.         WritePixel(RPort,Left + Push + Mult * (y + MidX - Left),-x + MidY);
  78.  
  79.         da -= (1 + x * 2);
  80.  
  81.         x++;
  82.     }
  83.     while(x <= y);
  84.  
  85.     Left += Width - 1 - Push;
  86.  
  87.     LTP_DrawLine(RPort,Left,Top + Height,Left,Top + Full - 1);
  88. }
  89.  
  90. STATIC VOID
  91. RenderTabs(struct RastPort *RPort,struct Gadget *gadget,TabInfo *Info,UWORD *Pens,LONG Pull)
  92. {
  93.     LONG    Width,Height;
  94.     LONG    i;
  95.     LONG    Pen;
  96.  
  97.     Width    = Info->TabWidth;
  98.     Height    = Info->TabHeight;
  99.  
  100.     SetRast(&Info->RPort,Pens[BACKGROUNDPEN]);
  101.  
  102.     for(i = 0 ; i < 4 ; i++)
  103.     {
  104.         if(i & 1)
  105.         {
  106.             if(Pens[SHINEPEN] == Pens[SHADOWPEN])
  107.                 Pen = BACKGROUNDPEN;
  108.             else
  109.                 Pen = SHADOWPEN;
  110.         }
  111.         else
  112.             Pen = SHINEPEN;
  113.  
  114.         LTP_SetAPen(&Info->RPort,Pens[Pen]);
  115.  
  116.         LTP_DrawLine(&Info->RPort,0,Height - 1 - i,gadget->Width - 1 - Info->Thick * i,Height - 1 - i);
  117.     }
  118.  
  119.     for(i = Info->Count - 1 ; i >= 0 ; i--)
  120.     {
  121.         if(i != Info->Current)
  122.             BltMaskBitMapRastPort(Info->Tabs[i].BitMap,0,0,&Info->RPort,Info->Tabs[i].Left,4,Width,Height - 6,ABC|ABNC|ANBC,Info->Mask);
  123.     }
  124.  
  125.     BltMaskBitMapRastPort(Info->Tabs[Info->Current].BitMap,0,0,&Info->RPort,Info->Tabs[Info->Current].Left,0,Width,Height - Pull,ABC|ABNC|ANBC,Info->Mask);
  126.  
  127.     WaitBlit();
  128.  
  129.     BltBitMapRastPort(Info->BitMap,0,0,RPort,gadget->LeftEdge,gadget->TopEdge + gadget->Height - (Info->TabHeight + 2),gadget->Width,Info->TabHeight,0xC0);
  130. }
  131.  
  132. STATIC VOID
  133. SetMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  134. {
  135.     TabInfo            *Info = INST_DATA(class,gadget);
  136.     struct TagItem    *Tag;
  137.     BOOL             NeedRefresh = FALSE;
  138.     BOOL             Disabled;
  139.  
  140.     Disabled = (BOOL)((gadget->Flags & GFLG_DISABLED) != 0);
  141.  
  142.     if(Tag = FindTagItem(GA_Disabled,SetInfo->ops_AttrList))
  143.     {
  144.         if(Tag->ti_Data && !Disabled || !Tag->ti_Data && Disabled)
  145.             NeedRefresh = TRUE;
  146.     }
  147.  
  148.     if(Tag = FindTagItem(TIA_Index,SetInfo->ops_AttrList))
  149.     {
  150.         LONG Index = Tag->ti_Data;
  151.  
  152.         if(Index >= Info->Count)
  153.             Index = Info->Count - 1;
  154.  
  155.         if(Index != Info->Current)
  156.         {
  157.             Info->Initial = Info->Current = Index;
  158.  
  159.             NeedRefresh = TRUE;
  160.         }
  161.     }
  162.  
  163.     if(NeedRefresh)
  164.     {
  165.         struct RastPort *RPort;
  166.  
  167.         if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
  168.         {
  169.             DoMethod((Object *)gadget,GM_RENDER,SetInfo->ops_GInfo,RPort,GREDRAW_REDRAW);
  170.  
  171.             ReleaseGIRPort(RPort);
  172.         }
  173.     }
  174. }
  175.  
  176. STATIC ULONG
  177. RenderMethod(struct IClass *class,struct Gadget *gadget,struct gpRender *RenderInfo)
  178. {
  179.     TabInfo *Info = INST_DATA(class,gadget);
  180.  
  181.     RenderTabs(RenderInfo->gpr_RPort,gadget,Info,RenderInfo->gpr_GInfo->gi_DrInfo->dri_Pens,RenderInfo->gpr_Redraw == GREDRAW_UPDATE ? 2 : 0);
  182.  
  183.     return(TRUE);
  184. }
  185.  
  186. STATIC VOID
  187. DisposeMethod(struct IClass *class,struct Gadget *gadget,Msg msg)
  188. {
  189.     TabInfo *Info = INST_DATA(class,gadget);
  190.  
  191.     if(Info->Mask || Info->Tabs || Info->BitMap)
  192.         WaitBlit();
  193.  
  194.     if(Info->Mask)
  195.     {
  196.         FreeRaster(Info->Mask,Info->TabWidth,Info->TabHeight);
  197.     }
  198.  
  199.     if(Info->Tabs)
  200.     {
  201.         LONG i;
  202.  
  203.         for(i = 0 ; i < Info->Count ; i++)
  204.             LTP_DeleteBitMap(Info->Tabs[i].BitMap,TRUE);
  205.  
  206.         FreeVec(Info->Tabs);
  207.     }
  208.  
  209.     LTP_DeleteBitMap(Info->BitMap,FALSE);
  210. }
  211.  
  212. STATIC ULONG
  213. NewMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  214. {
  215.     if(gadget = (struct Gadget *)DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo))
  216.     {
  217.         TabInfo            *Info = INST_DATA(class,gadget);
  218.         struct TagItem    *Tag,*TagList = SetInfo->ops_AttrList;
  219.         struct TextAttr    *FontAttr;
  220.         LONG             Width,Height;
  221.         struct DrawInfo    *DrawInfo;
  222.         STRPTR            *Labels;
  223.         struct Screen    *Screen;
  224.  
  225.         Width        = 0;
  226.         Height        = 0;
  227.  
  228.         FontAttr    = NULL;
  229.         DrawInfo    = NULL;
  230.         Labels        = NULL;
  231.         Screen        = NULL;
  232.  
  233.         memset(Info,0,sizeof(TabInfo));
  234.  
  235.         while(Tag = NextTagItem(&TagList))
  236.         {
  237.             switch(Tag->ti_Tag)
  238.             {
  239.                 case GA_Width:
  240.                     Width = Tag->ti_Data;
  241.                     break;
  242.  
  243.                 case GA_Height:
  244.                     Height = Tag->ti_Data;
  245.                     break;
  246.  
  247.                 case TIA_Labels:
  248.                     Labels = (STRPTR *)Tag->ti_Data;
  249.                     break;
  250.  
  251.                 case TIA_Font:
  252.                     FontAttr = (struct TextAttr *)Tag->ti_Data;
  253.                     break;
  254.  
  255.                 case TIA_Screen:
  256.                     Screen = (struct Screen *)Tag->ti_Data;
  257.                     break;
  258.  
  259.                 case TIA_Index:
  260.                     Info->Current = Tag->ti_Data;
  261.                     break;
  262.  
  263.                 case TIA_DrawInfo:
  264.                     DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  265.                     break;
  266.             }
  267.         }
  268.  
  269.         if(Labels)
  270.         {
  271.             while(Labels[Info->Count])
  272.                 Info->Count++;
  273.         }
  274.  
  275.         if(Screen && DrawInfo && FontAttr && Width && Height && Labels && Info->Count)
  276.         {
  277.             struct TextFont *Font;
  278.  
  279.             if(Font = OpenFont(FontAttr))
  280.             {
  281.                 struct RastPort *RPort = &Info->RPort;
  282.  
  283.                 InitRastPort(RPort);
  284.  
  285.                 SetFont(RPort,Font);
  286.  
  287.                 if(Height >= RPort->TxHeight + 11)
  288.                 {
  289.                     LONG i,Len,MaxWidth,Remain;
  290.                     LONG Lean;
  291.  
  292.                     if(Info->Current < 0)
  293.                         Info->Current = 0;
  294.                     else
  295.                     {
  296.                         if(Info->Current >= Info->Count)
  297.                             Info->Current = Info->Count - 1;
  298.                     }
  299.  
  300.                     Lean = (TextLength(RPort,"O",1) + 1) / 2;
  301.  
  302.                     Info->Thick    = (DrawInfo->dri_Resolution.Y + DrawInfo->dri_Resolution.X - 1) / DrawInfo->dri_Resolution.X;
  303.  
  304.                     if(Info->Thick < 1)
  305.                         Info->Thick = 1;
  306.  
  307.                     for(i = MaxWidth = 0 ; i < Info->Count ; i++)
  308.                     {
  309.                         if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  310.                             MaxWidth = Len;
  311.                     }
  312.  
  313.                     MaxWidth = Info->Thick + (Lean + Info->Thick - 1 + Info->Thick + MaxWidth + Info->Thick + Lean + Info->Thick - 1) + Info->Thick;
  314.  
  315.                     Remain = (Width - MaxWidth - 5 * Info->Thick) / (Info->Thick * 4);
  316.  
  317.                     if(Remain >= Info->Count - 1)
  318.                     {
  319.                         if(Info->Tabs = (TabEntry *)AllocVec(sizeof(TabEntry) * Info->Count,MEMF_ANY|MEMF_CLEAR))
  320.                         {
  321.                             STATIC const BYTE PenNumbers[] =
  322.                             {
  323.                                 BACKGROUNDPEN,
  324.                                 SHINEPEN,
  325.                                 SHADOWPEN,
  326.                                 TEXTPEN
  327.                             };
  328.  
  329.                             struct BitMap     Mask;
  330.                             LONG             Depth;
  331.                             LONG             MaxPen;
  332.                             UWORD            *Pens = DrawInfo->dri_Pens;
  333.                             BOOL             GotIt = TRUE;
  334.  
  335.                             memset(&Mask,0,sizeof(Mask));
  336.  
  337.                             for(i = 0, MaxPen = -1 ; i < sizeof(PenNumbers) ; i++)
  338.                             {
  339.                                 if(Pens[PenNumbers[i]] > MaxPen)
  340.                                     MaxPen = Pens[PenNumbers[i]];
  341.                             }
  342.  
  343.                             Depth = 8;    /* For the sake of the compiler initialize this. */
  344.  
  345.                             for(i = 1 ; i <= 8 ; i++)
  346.                             {
  347.                                 if(MaxPen < (1 << i))
  348.                                 {
  349.                                     Depth = i;
  350.                                     break;
  351.                                 }
  352.                             }
  353.  
  354.                             Info->TabWidth    = MaxWidth;
  355.                             Info->TabHeight    = 4 + RPort->TxHeight + 5;
  356.  
  357.                             InitBitMap(&Mask,1,Info->TabWidth,Info->TabHeight);
  358.  
  359.                             Mask.Planes[1] = NULL;
  360.  
  361.                             for(i = 0 ; GotIt && i < 2 ; i++)
  362.                             {
  363.                                 if(!(Mask.Planes[i] = (PLANEPTR)AllocRaster(Info->TabWidth,Info->TabHeight)))
  364.                                     GotIt = FALSE;
  365.                             }
  366.  
  367.                             for(i = 0 ; GotIt && i < Info->Count ; i++)
  368.                             {
  369.                                 if(!(Info->Tabs[i].BitMap = LTP_CreateBitMap(Info->TabWidth,Info->TabHeight,Depth,NULL,TRUE)))
  370.                                     GotIt = FALSE;
  371.                             }
  372.  
  373.                             if(GotIt)
  374.                             {
  375.                                 Depth = LTP_GetDepth(Screen->RastPort.BitMap);
  376.  
  377.                                 if(!(Info->BitMap = LTP_CreateBitMap(gadget->Width,Info->TabHeight,Depth,Screen->RastPort.BitMap,FALSE)))
  378.                                     GotIt = FALSE;
  379.                             }
  380.  
  381.                             if(GotIt)
  382.                             {
  383.                                 struct TmpRas     TmpRas;
  384.                                 LONG             j,Len,Offset,P